package com.mspbots.cw.trigger;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mspbots.api.client.CoreClient;
import com.mspbots.cw.amqp.model.Ticket;
import com.mspbots.cw.amqp.model.TriggerEvent;
import com.mspbots.cw.request.TenantRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static com.mspbots.common.TriggerEvent.CW_TICKET_SCHEDULE;


/**
 * com.mspbots.cw.trigger.TicketScheduleEvent
 *
 * @author Jason
 * @date 2019/12/13
 **/
@Slf4j
@Service
@RequiredArgsConstructor
public class TicketScheduleEvent {

    private final CoreClient coreClient;
    private final ObjectMapper objectMapper;
    private final RabbitMessagingTemplate messagingTemplate;

//    @Scheduled(fixedRate = 60 * 1000)
    @Scheduled(fixedDelayString ="${mspbots.fixedDelay.ticketSchedule}")
    public void produce() {
        log.debug("TicketScheduleEvent...");
        Map<String, Object> tenantParams = Map.of("statusId", 1);
        JsonNode tenantNode = coreClient.get("/tenant/list", tenantParams).block();
        log.debug("tenants tenantNode {}", tenantNode);
        List<TenantRequest> list = objectMapper.convertValue(tenantNode, new TypeReference<List<TenantRequest>>() {
        });
        log.debug("tenants list size {}", list == null ? "0" : list.size());
        assert list != null;
        LocalDateTime updatedTimeStart = LocalDateTime.now().minusHours(2);
        int pageSize = 20;
        list.parallelStream().distinct().forEach(tenantDTO -> {
            Map<String, Object> ticketsParams = Map.of("tenantId", tenantDTO.getId(),
                    "updatedTimeStart", updatedTimeStart,
                    "size", pageSize
            );
            JsonNode ticketNode = coreClient.get("/tickets/list-for-rule", ticketsParams).block();
            Ticket ticketPage1 = objectMapper.convertValue(ticketNode, new TypeReference<Ticket>() {
            });


            List<Ticket> ticketListTemp1 = objectMapper.convertValue(ticketPage1.getRecords(), new TypeReference<List<Ticket>>() {
            });
            List<Ticket> ticketList = new ArrayList<>(ticketListTemp1);
            for (int i = 1; i < ticketPage1.getPages(); i++) {
                Map<String, Object> params = Map.of("tenantId", tenantDTO.getId(),
                        "updatedTimeStart", updatedTimeStart,
                        "size", pageSize,
                        "current", i + 1
                );
                JsonNode ticketCurrent = coreClient.get("/tickets/list-for-rule", params).block();
                JsonNode records = objectMapper.convertValue(ticketCurrent, new TypeReference<Ticket>() {
                }).getRecords();
                List<Ticket> ticketListTemp = objectMapper.convertValue(records, new TypeReference<List<Ticket>>() {
                });
                ticketList.addAll(ticketListTemp);
            }
            if (!CollectionUtils.isEmpty(ticketList)) {
                log.info("tenant {} ticket size {}", tenantDTO.getId(), ticketList.size());
                ticketList.parallelStream().distinct().forEach(ticket -> {
                    Map<String, Object> userMappingParam = Map.of(
                            "tenantId", ticket.getTenantId(),
                            "identifier", ticket.getUpdatedBy());
                    log.debug("tID: {}, tenantID: {} ,ticket id :{}", tenantDTO.getId(),ticket.getTenantId(),ticket.getId());

                    JsonNode userMapping = coreClient.get("/user-mapping/detail", userMappingParam).block();
                    if (userMapping != null) {
                        try {
                            String ticketStr = objectMapper.writeValueAsString(ticket);
                            JsonNode payload = objectMapper.readTree(ticketStr);
                            TriggerEvent triggerEvent = new TriggerEvent();
                            triggerEvent.setTenantId(userMapping.get("tenantId").asLong());
                            triggerEvent.setEventName(CW_TICKET_SCHEDULE.getEvent());
                            triggerEvent.setScope(CW_TICKET_SCHEDULE.getScope());
                            triggerEvent.setPayload(payload);
                            triggerEvent.setUserInfo(userMapping);
                            log.debug("ticket schedule {} {}", ticket.getTenantId(), ticket.getCwId());
                            this.messagingTemplate.convertAndSend("msp.trigger.event", "", triggerEvent);
                            log.debug("cw msp.trigger.event ScheduleTicket [{}] ", this.objectMapper.convertValue(triggerEvent,JsonNode.class));
                        } catch (JsonProcessingException e) {
                            e.printStackTrace();
                        }
                    }

                });
            }


//            if (!CollectionUtils.isEmpty(ticketList)) {
//                log.info("tenant {} ticket size {}", tenantDTO.getId(), ticketList.size());
//                ticketList.stream().parallel().forEach(tenantTicketDTO -> {
//                    Map<String, Object> userMappingParam = Map.of(
//                            "tenantId", tenantTicketDTO.getTenantId(),
//                            "identifier",tenantTicketDTO.getExtend().get("_info").get("updatedBy").asText()
//                    );
//
//                    JsonNode userMapping = coreClient.get("/user-mapping/detail", userMappingParam).block();
//                    if (userMapping != null) {
//                        TriggerEventDTO triggerEventDTO = new TriggerEventDTO();
//                        triggerEventDTO.setTenantId(userMapping.get("tenantId").asLong());
//                        triggerEventDTO.setEventName(CW_TICKET_SCHEDULE.getEvent());
//                        triggerEventDTO.setScope(CW_TICKET_SCHEDULE.getScope());
//                        triggerEventDTO.setPayload(tenantTicketDTO.getExtend());
//                        triggerEventDTO.setUserInfo(userMapping);
//                        this.messagingTemplate.convertAndSend("msp.trigger.event", "", triggerEventDTO);
//                    }
//
//                });
//            } else {
//                log.info("tenant {} ticket empty");
//            }
        });
    }

}
